﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
using System.Runtime.Versioning;
using System.Text;
using System.Text.RegularExpressions;
using UtilZ.Dotnet.Ex.Model;
using UtilZ.Dotnet.Ex.ZLog;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// 网络通信相关的辅助类
    /// </summary>
    public static class NetHelper
    {
        private static SocketError[] _disconnectSocketErrors = null;
        private static SocketError[] _connectFailRepeatSocketErrorArr = null;
        private static SocketError[] _sendFailRepeatSocketErrorArr = null;

        /// <summary>
        /// SocketError是否属于断开连接错误[返回值：是返回true,不是返回false]
        /// </summary>
        /// <param name="socketError">SocketError</param>
        /// <returns>是返回true,不是返回false</returns>
        public static bool SocketErrorIsDisconnect(SocketError socketError)
        {
            if (_disconnectSocketErrors == null)
            {
                /***********************************************************************************************
                * socket断开异常处理
                * sex.ErrorCode:
                * 10054   Message = "远程主机强迫关闭了一个现有的连接。"
                * 10053   Message = "你的主机中的软件中止了一个已建立的连接。"
                * 10004   Message = "一个封锁操作被对 WSACancelBlockingCall 的调用中断。"-接收线程被终止
                * 10058   Message = "由于以前的关闭调用，套接字在那个方向已经关闭，发送或接收数据的请求没有被接受。"
                ***********************************************************************************************/
                _disconnectSocketErrors = new SocketError[]
                {
                    SocketError.OperationAborted,
                    SocketError.Interrupted,
                    SocketError.ConnectionReset,//对方断开
                    SocketError.ConnectionAborted,
                    SocketError.Shutdown,
                    SocketError.HostDown,
                    SocketError.Disconnecting,
                    SocketError.ConnectionRefused,
                    SocketError.NetworkReset,
                    SocketError.NetworkDown,
                    //SocketError.TimedOut,
                };
            }

            return _disconnectSocketErrors.Contains(socketError);
        }

        /// <summary>
        /// SocketError是否属于发送数据失败错误[返回值：是返回true,不是返回false]
        /// </summary>
        /// <param name="socketError">SocketError</param>
        /// <returns>是返回true,不是返回false</returns>
        public static bool SocketErrorIsSendFail(SocketError socketError)
        {
            if (_sendFailRepeatSocketErrorArr == null)
            {
                _sendFailRepeatSocketErrorArr = new SocketError[]
               {
                    SocketError.SocketError,
                    SocketError.OperationAborted,
                    SocketError.IOPending,
                    SocketError.TooManyOpenSockets,
                    SocketError.WouldBlock,
                    SocketError.NetworkDown,
                    SocketError.ConnectionReset,
                    SocketError.NotConnected,
                    SocketError.Shutdown,
                    SocketError.HostDown,
                    SocketError.ProcessLimit,
                    SocketError.SystemNotReady
               };
            }

            return _sendFailRepeatSocketErrorArr.Contains(socketError);
        }

        /// <summary>
        /// SocketError是否属于建立连接失败错误[返回值：是返回true,不是返回false]
        /// </summary>
        /// <param name="socketError">SocketError</param>
        /// <returns>是返回true,不是返回false</returns>
        public static bool SocketErrorIsConnectFail(SocketError socketError)
        {
            if (_connectFailRepeatSocketErrorArr == null)
            {
                _connectFailRepeatSocketErrorArr = new SocketError[]
               {
                    SocketError.TooManyOpenSockets,
                    SocketError.NetworkDown,
                    SocketError.ConnectionReset,
                    SocketError.TimedOut,
                    SocketError.ConnectionRefused,
                    SocketError.HostDown,
                    SocketError.HostUnreachable
               };
            }

            return _connectFailRepeatSocketErrorArr.Contains(socketError);
        }




        /// <summary>
        /// UDP发送数据标准长度值,548
        /// </summary>
        public const int UDP_PACKAGE_STANDARD = 548;

        /// <summary>
        /// UDP收发送数据不分包的最大长度值,1472
        /// </summary>
        public const int UDP_NO_SPLIT_PACKAGE_MAX = 1472;

        /// <summary>
        /// UDP单次收发数据包最大长度65507
        /// </summary>
        public const int UDP_PACKAGE_MAX = 65507;

        /// <summary>
        /// TCP收发数据缓存长度值,8192
        /// </summary>
        public const int TCP_PACKAGE = 8192;







        /// <summary>
        /// 创建udp Socket
        /// </summary>
        /// <param name="localEndPoint">本地绑定EndPoint</param>
        /// <param name="receiveBufferSize">接收数据缓存</param>
        /// <param name="sendBufferSize">发送数据缓存</param>
        /// <returns>udp Socket</returns>
        public static Socket CreateUdpClient(EndPoint localEndPoint, int receiveBufferSize = NetHelper.UDP_PACKAGE_MAX, int sendBufferSize = NetHelper.UDP_PACKAGE_MAX)
        {
            var client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
            client.ReceiveBufferSize = receiveBufferSize;
            client.SendBufferSize = sendBufferSize;
            client.EnableBroadcast = false;
            //client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, 1);
            try
            {
                client.Bind(localEndPoint);
            }
            catch (SocketException sex)
            {
                client.Dispose();
#if CORE
                throw new SocketException(sex.ErrorCode, $"{sex.Message}本地绑定EndPoint:{GetIPPortString(localEndPoint)}");
#else
                throw new Exception($"{sex.Message}本地绑定EndPoint:{GetIPPortString(localEndPoint)}", sex);
#endif
            }
            //如果没有这两行代码,则windows底层BUG会在接收抛出异常,并将socket重置,然后再也收不到数据
            const int SIO_UDP_CONNRESET = -1744830452;
            client.IOControl(SIO_UDP_CONNRESET, new byte[] { 0, 0, 0, 0 }, null);
            return client;
        }

        /// <summary>
        /// 创建tcp Socket
        /// </summary>
        /// <param name="localEndPoint">本地绑定EndPoint</param>
        /// <returns></returns>
        public static Socket CreateTcpClient(EndPoint localEndPoint = null)
        {
#if NET4_0
            var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
#else
            var client = new Socket(SocketType.Stream, ProtocolType.Tcp);
#endif

            if (localEndPoint != null)
            {
                try
                {
                    client.Bind(localEndPoint);
                }
                catch (SocketException sex)
                {
                    client.Dispose();
#if CORE
                    throw new SocketException(sex.ErrorCode, $"{sex.Message}本地绑定EndPoint:{GetIPPortString(localEndPoint)}");
#else
                    throw new Exception($"{sex.Message}本地绑定EndPoint:{GetIPPortString(localEndPoint)}", sex);
#endif
                }
            }

            return client;
        }









        /// <summary>
        /// 获取EndPoint String
        /// </summary>
        /// <param name="endPoint">EndPoint</param>
        /// <returns>IP String</returns>
        public static string GetIPString(EndPoint endPoint)
        {
            if (endPoint == null)
            {
                return string.Empty;
            }

            string ipStr;
            try
            {
                if (endPoint is IPEndPoint)
                {
                    //::ffff:127.0.0.1
                    var ipEndPoint = (IPEndPoint)endPoint;
                    ipStr = ipEndPoint.Address.ToString();
                    int captureStartIndex = ipStr.LastIndexOf(':');
                    if (captureStartIndex >= 0)
                    {
                        ipStr = ipStr.Substring(captureStartIndex + 1);
                    }

                    //ipStr = $"{ipStr}:{ipEndPoint.Port}";
                }
                else
                {
                    ipStr = endPoint.ToString();
                }
            }
            catch (Exception ex)
            {
                ipStr = endPoint.ToString();
                ZLoger.Error(ex, "转换IP地址异常");
            }

            return ipStr;
        }

        /// <summary>
        /// 获取EndPoint String ,带端口
        /// </summary>
        /// <param name="endPoint">EndPoint</param>
        /// <returns>IP String</returns>
        public static string GetIPPortString(EndPoint endPoint)
        {
            if (endPoint == null)
            {
                return string.Empty;
            }

            string ipStr;
            try
            {
                if (endPoint is IPEndPoint)
                {
                    //::ffff:127.0.0.1
                    var ipEndPoint = (IPEndPoint)endPoint;
                    ipStr = ipEndPoint.Address.ToString();
                    int captureStartIndex = ipStr.LastIndexOf(':');
                    if (captureStartIndex >= 0)
                    {
                        ipStr = ipStr.Substring(captureStartIndex + 1);
                    }

                    ipStr = $"{ipStr}:{ipEndPoint.Port}";
                }
                else if (endPoint is DnsEndPoint)
                {
                    var dnsEndPoint = (DnsEndPoint)endPoint;
                    ipStr = $"{dnsEndPoint.Host}:{dnsEndPoint.Port}";
                }
                //else if (endPoint is UnixDomainSocketEndPoint)
                //{
                //    var unixDomainSocketEndPoint = (UnixDomainSocketEndPoint)endPoint;
                //    ipStr = unixDomainSocketEndPoint.;
                //}
                else
                {
                    ipStr = endPoint.ToString();
                }
            }
            catch (Exception ex)
            {
                ipStr = endPoint.ToString();
                ZLoger.Error(ex, "转换IP地址异常");
            }

            return ipStr;
        }



        /// <summary>
        /// 验证IP是否是一个IPV4地址[是合法的ipv4地址返回true,否则返回flase]
        /// </summary>
        /// <param name="ipStr">ipv4字符串</param>
        /// <returns>是合法的ipv4地址返回true,否则返回flase</returns>
        public static bool ValidateIPV4(string ipStr)
        {
            return Regex.IsMatch(ipStr, RegexConstant.IPV4Reg);
        }



        /// <summary>
        /// IPV4地址转换为Int32整数(返回值存在负数)
        /// </summary>
        /// <param name="ipStr">ip字符串</param>
        /// <returns>ip对应的整数</returns>
        public static int IPV4ToInt32(string ipStr)
        {
            if (!ValidateIPV4(ipStr))
            {
                throw new Exception(string.Format("服务端IP:{0}不是有效有IPV4值", ipStr));
            }

            string[] items = ipStr.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            return int.Parse(items[0]) << 24
                    | int.Parse(items[1]) << 16
                    | int.Parse(items[2]) << 8
                    | int.Parse(items[3]);
        }

        /// <summary>
        /// IPV4地址转换为Int32整数(返回值存在负数)
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <returns>ip对应的整数</returns>
        public static int IPV4ToInt32(IPAddress ip)
        {
            byte[] arr = ip.GetAddressBytes();
            return ((int)arr[0]) << 24
                   | ((int)arr[1]) << 16
                   | ((int)arr[2]) << 8
                   | ((int)arr[3]);
        }




        /// <summary>
        /// IPV4地址转换为Int64整数(返回值全为正数)
        /// </summary>
        /// <param name="ipStr">ip字符串</param>
        /// <returns>ip对应的整数</returns>
        public static long IPV4ToInt64(string ipStr)
        {
            if (!ValidateIPV4(ipStr))
            {
                throw new Exception(string.Format("IP:{0}不是有效有IPV4值", ipStr));
            }

            string[] items = ipStr.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            return long.Parse(items[0]) << 24
                    | long.Parse(items[1]) << 16
                    | long.Parse(items[2]) << 8
                    | long.Parse(items[3]);
        }

        /// <summary>
        /// IPV4地址转换为Int32整数(返回值存在负数)
        /// </summary>
        /// <param name="ip">ip地址</param>
        /// <returns>ip对应的整数</returns>
        public static long IPV4ToInt64(IPAddress ip)
        {
            byte[] arr = ip.GetAddressBytes();
            return ((long)arr[0]) << 24
                   | ((long)arr[1]) << 16
                   | ((long)arr[2]) << 8
                   | ((long)arr[3]);
        }

        /// <summary>
        /// 整数转换为IP地址
        /// </summary>
        /// <param name="ipValue">ip对应的整数值</param>
        /// <returns>IP地址</returns>
        public static string IntToIp(long ipValue)
        {
            var sb = new StringBuilder();
            sb.Append((ipValue >> 24) & 0xFF).Append(".");
            sb.Append((ipValue >> 16) & 0xFF).Append(".");
            sb.Append((ipValue >> 8) & 0xFF).Append(".");
            sb.Append(ipValue & 0xFF);
            return sb.ToString();
        }



        /// <summary>
        /// 验证一个端口号是否可用
        /// </summary>
        /// <param name="port">需要验证的端口号</param>
        /// <returns>如果可用返回true,否则返回false</returns>
        public static bool CheckPortAvailable(int port)
        {
            using (Socket sk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP))
            {
                bool result = false;
                try
                {
                    sk.Bind(new IPEndPoint(IPAddress.Any, port));
                    result = true;
                }
                catch (Exception)
                {
                    result = false;
                }

                return result;
            }
        }

        /// <summary>
        /// 验证一个端口号是否被使用
        /// </summary>
        /// <param name="port">需要验证的端口号</param>
        /// <returns>如果被使用返回true,否则返回false</returns>
        public static bool CheckPortAvailable2(int port)
        {
            List<int> tcpPorts;
            List<int> udpPorts;
            List<int> ipPorts;
            var allports = GetUsedPorts(out tcpPorts, out udpPorts, out ipPorts);
            return allports.Contains(port);
        }

        /// <summary>
        /// 获取已使用的端口号
        /// </summary>
        /// <param name="tcpPorts">TCP占用的端口号</param>
        /// <param name="udpPorts">UDP占用的端口号</param>
        /// <param name="ipPorts">ip占用的端口号</param>
        /// <returns>当前所有已使用端口号集合</returns>
        public static List<int> GetUsedPorts(out List<int> tcpPorts, out List<int> udpPorts, out List<int> ipPorts)
        {
            var allports = new List<int>();
            tcpPorts = new List<int>();
            udpPorts = new List<int>();
            ipPorts = new List<int>();

            //获取本地计算机的网络连接和通信统计数据的信息
            IPGlobalProperties ipGolobalProperties = IPGlobalProperties.GetIPGlobalProperties();

            //tcp监听协议
            IPEndPoint[] ipsTCP = ipGolobalProperties.GetActiveTcpListeners();
            foreach (var ep in ipsTCP)
            {
                tcpPorts.Add(ep.Port);
                allports.Add(ep.Port);
            }
            tcpPorts = tcpPorts.OrderBy((p) => { return p; }).Distinct().ToList();

            //udp监听协议
            IPEndPoint[] ipsUDP = ipGolobalProperties.GetActiveUdpListeners();
            foreach (var ep in ipsUDP)
            {
                udpPorts.Add(ep.Port);
                allports.Add(ep.Port);
            }
            udpPorts = udpPorts.OrderBy((p) => { return p; }).Distinct().ToList();

            //返回本地计算机上的Internet协议连接信息
            TcpConnectionInformation[] tcpConninfoArray = ipGolobalProperties.GetActiveTcpConnections();
            foreach (var conn in tcpConninfoArray)
            {
                ipPorts.Add(conn.LocalEndPoint.Port);
                allports.Add(conn.LocalEndPoint.Port);
            }
            ipPorts = ipPorts.OrderBy((p) => { return p; }).Distinct().ToList();

            allports = allports.OrderBy((p) => { return p; }).Distinct().ToList();
            return allports;
        }

        /// <summary>
        /// 获取已使用的端口号
        /// </summary>
        /// <returns>当前所有已使用端口号集合</returns>
        public static List<int> GetUsedPorts()
        {
            List<int> tcpPorts, udpPorts, ipPorts;
            return GetUsedPorts(out tcpPorts, out udpPorts, out ipPorts);
        }





        /// <summary>
        /// 根据服务器IP获取能连接到该服务器的其中一个客户端面IP地址
        /// </summary>
        /// <param name="serverIp">服务器IP</param>
        /// <returns>找到的客户端IP地址</returns>
        [SupportedOSPlatform(EnvironmentEx.WINDOWS)]
        public static IPAddress GetPingServerIpClientIp(string serverIp)
        {
            IPAddress serverIpAddr;
            if (!IPAddress.TryParse(serverIp, out serverIpAddr))
            {
                throw new Exception(string.Format("服务端IP:{0}不是有效有IP值", serverIp));
            }

            IPAddress ipAddrRet = null;
            IPAddress[] ipaddrs = Dns.GetHostAddresses(Dns.GetHostName());

            foreach (IPAddress ipAddr in ipaddrs)
            {
                //ipAddr.AddressFamily :对于 IPv4，返回 InterNetwork；对于 IPv6，返回 InterNetworkV6。
                if (serverIpAddr.AddressFamily != ipAddr.AddressFamily)
                {
                    continue;
                }

                if (ValidateClientIpPingServerIp(ipAddr.ToString(), serverIp))
                {
                    ipAddrRet = ipAddr;
                    break;
                }
            }

            return ipAddrRet;
        }

        /// <summary>
        /// 验证本机中的一个IP是否能连接到服务端
        /// </summary>
        /// <param name="clientIp">客户端IP</param>
        /// <param name="serverIp">服务端IP</param>
        /// <param name="count">尝试次数,默认4次.值越大,所需要的时间就越长</param>
        /// <returns>能ping通:true,否则false</returns>
        [SupportedOSPlatform(EnvironmentEx.WINDOWS)]
        public static bool ValidateClientIpPingServerIp(string clientIp, string serverIp, int count = 4)
        {
            IPAddress serverIpAddr, clientIpAddr;
            if (!IPAddress.TryParse(clientIp, out clientIpAddr))
            {
                throw new Exception(string.Format("客户端IP:{0}不是有效有IP值", clientIp));
            }
            if (!IPAddress.TryParse(serverIp, out serverIpAddr))
            {
                throw new Exception(string.Format("服务端IP:{0}不是有效有IP值", serverIp));
            }
            //ipAddr.AddressFamily :对于 IPv4，返回 InterNetwork；对于 IPv6，返回 InterNetworkV6。
            if (serverIpAddr.AddressFamily != clientIpAddr.AddressFamily)
            {
                throw new Exception(string.Format("服务端IP:{0}与客户端IP:{1}不是同一类IP", serverIp, clientIp));
            }

            //string app = "PING.EXE";
            //int count = 4;
            //string args = string.Format("{0} -S {1} -n {2}", serverIp, clientIp, count);

            string commandLine = $"ping {serverIp} -S {clientIp} -n {count}";
            string pingResultStr = ProcessEx.ExecuteCommand(commandLine);
            pingResultStr = pingResultStr.Replace(" ", string.Empty);

            Match receiveCountMatch = Regex.Match(pingResultStr, @"已接收=(?<rcount>\d+)");
            string receiveCountStr = receiveCountMatch.Groups["rcount"].Value;
            if (string.IsNullOrEmpty(receiveCountStr))
            {
                return false;
            }
            //已接收包数
            int receiveCount = int.Parse(receiveCountStr);

            //时间
            MatchCollection mc = Regex.Matches(pingResultStr, @"<(?<rtime>\d+)ms");

            return mc.Count > 0 && receiveCount > 0;
        }

        /// <summary>
        /// 验证本机能否Ping通指定IP或主机名的主机[成功返回true;否则返回false]
        /// </summary>
        /// <param name="hostNameOrAddress">IP或主机名</param>
        /// <param name="millisecondsTimeout">超时时间,单位毫秒.默认4000</param>
        /// <returns>成功返回true;否则返回false</returns>
        public static bool Ping(string hostNameOrAddress, int millisecondsTimeout = 4000)
        {
            bool pingStatus = false;
            using (var ping = new Ping())
            {
                byte[] buffer = Encoding.ASCII.GetBytes("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

                try
                {
                    PingReply reply = ping.Send(hostNameOrAddress, millisecondsTimeout, buffer);
                    pingStatus = (reply.Status == IPStatus.Success);
                }
                catch (Exception)
                {
                    pingStatus = false;
                }
            }

            return pingStatus;
        }

        /// <summary>
        /// 对指定地址的主机尝试Ping操作[成功返回true;否则返回false]
        /// </summary>
        /// <param name="ip">目标IP</param>
        /// <param name="millisecondsTimeout">超时时间,单位毫秒.默认4000</param>
        /// <returns>成功返回true,失败返回false</returns>
        public static bool Ping(IPAddress ip, int millisecondsTimeout = 4000)
        {
            using (var ping = new Ping())
            {
                PingReply result = ping.Send(ip, millisecondsTimeout);
                return result.Status == IPStatus.Success;
            }

            //IntPtr icmpHandle = NativeMethods.IcmpCreateFile();
            //ICMP_OPTIONS icmpOptions = new ICMP_OPTIONS();
            //icmpOptions.Ttl = 255;
            //ICMP_ECHO_REPLY icmpReply = new ICMP_ECHO_REPLY();
            //string sData = "x";
            //int iReplies = NativeMethods.IcmpSendEcho(icmpHandle, BitConverter.ToInt32(ip.GetAddressBytes(), 0), sData, (short)sData.Length, ref icmpOptions, ref icmpReply, Marshal.SizeOf(icmpReply), 30);
            //NativeMethods.IcmpCloseHandle(icmpHandle);
            //if (icmpReply.Status == 0)
            //{
            //    return true;
            //}
            //else
            //{
            //    return false;
            //}
        }




        /// <summary>
        /// 根据寻址方案获取本机符合该方案的所有IP地址数组
        /// </summary>
        /// <param name="addressFamily">寻址方案</param>
        /// <returns>IP地址数组</returns>
        public static IPAddress[] GetAllIPV4(AddressFamily addressFamily = AddressFamily.InterNetwork)
        {
            string invalidIpPre;
            switch (Environment.OSVersion.Platform)
            {
                case PlatformID.Win32NT:
                case PlatformID.Win32Windows:
                case PlatformID.WinCE:
                case PlatformID.Win32S:
                    //169.254.x.x
                    invalidIpPre = "169.254";
                    break;
                default:
                    invalidIpPre = "0.0.0.0";
                    break;
            }

            List<IPAddress> ipAddressesList = new List<IPAddress>();
            NetworkInterface[] networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
            UnicastIPAddressInformationCollection unicastAddresses;
            foreach (var networkInterface in networkInterfaces)
            {
                switch (networkInterface.NetworkInterfaceType)
                {
                    case NetworkInterfaceType.Ethernet:
                    case NetworkInterfaceType.Fddi:
                    case NetworkInterfaceType.Ethernet3Megabit:
                    case NetworkInterfaceType.Slip:
                    case NetworkInterfaceType.Atm:
                    case NetworkInterfaceType.GenericModem:
                    case NetworkInterfaceType.FastEthernetT:
                    case NetworkInterfaceType.FastEthernetFx:
                    case NetworkInterfaceType.Wireless80211:
                    case NetworkInterfaceType.AsymmetricDsl:

                    case NetworkInterfaceType.RateAdaptDsl:
                    case NetworkInterfaceType.SymmetricDsl:
                    case NetworkInterfaceType.VeryHighSpeedDsl:
                    case NetworkInterfaceType.IPOverAtm:
                    case NetworkInterfaceType.GigabitEthernet:

#if NET4_0

#else
                    case NetworkInterfaceType.Wman:
                    case NetworkInterfaceType.Wwanpp:
                    case NetworkInterfaceType.Wwanpp2:
#endif
                        unicastAddresses = networkInterface.GetIPProperties().UnicastAddresses;
                        if (unicastAddresses == null || unicastAddresses.Count == 0)
                        {
                            continue;
                        }

                        foreach (var unicastAdd in unicastAddresses)
                        {
                            if (unicastAdd.Address.AddressFamily != addressFamily ||
                                IPAddress.IsLoopback(unicastAdd.Address) ||
                                unicastAdd.Address.ToString().StartsWith(invalidIpPre))
                            {
                                continue;
                            }

                            ipAddressesList.Add(unicastAdd.Address);
                        }
                        break;
                    default:
                        continue;
                }
            }

            return ipAddressesList.ToArray();

            //return NetworkInterface.GetAllNetworkInterfaces()
            //    .Where(p0 => p0.NetworkInterfaceType == NetworkInterfaceType.Ethernet || p0.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || p0.NetworkInterfaceType == NetworkInterfaceType.GigabitEthernet)
            //    .Select(p1 => p1.GetIPProperties())
            //    .SelectMany(p2 => p2.UnicastAddresses)
            //    .Where(p3 => p3.Address.AddressFamily == addressFamily && !IPAddress.IsLoopback(p3.Address) && !p3.Address.ToString().StartsWith(invalidIpPre))
            //    .Select(p4 => p4.Address).ToArray();



            //IPHostEntry ipHostEntry = Dns.GetHostEntry(Dns.GetHostName());
            //return ipHostEntry.AddressList.Where(t => t.AddressFamily == addressFamily).ToArray();
        }




    }
}
